package com.yw.ffmpeg.player;

import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioTrack;
import android.net.rtp.AudioStream;

import com.yw.ffmpeg.utils.LogUtil;

import java.io.File;
import java.io.FileInputStream;

/**
 * @ProjectName: AndroidFFMpeg
 * @Package: com.yw.ffmpeg.player
 * @ClassName: AudioTrackPlayer
 * @Description: 使用AudioTrack播放音频文件
 * @Author: wei.yang
 * @CreateDate: 2021/8/31 10:26
 * @UpdateUser: 更新者：wei.yang
 * @UpdateDate: 2021/8/31 10:26
 * @UpdateRemark: 更新说明：
 * @Version: 1.0
 * * ps:
 *  * 1.AudioTrack是Android SDK提供的最底层的音频播放API，因此只允许输入裸数据
 *  * <p>
 *  * AudioTrack的工作流程
 *  * 1.根据音频参数信息配置出一个AudioTrack实例
 *  * 2.调用play方法将AudioTrack切换到播放状态
 *  * 3.启动播放线程，循环向AudioTrack缓冲区中写入音频数据
 *  * 4.当数据写完或者停止播放的时候，停止播放线程并释放所有资源
 *  * <p>
 *  * AudioTrack的构造函数
 *  * AudioTrack(int streamType,int sampleRateInHz,int channelConfig,int audioFormat,int bufferSizeInBytes,int mode)
 *  * 1.streamType:音频管理策略。如：在AudioManager中的STREAM_VOICE_CALL：电话声音、STREAM_SYSTEM：系统声音、STREAM_RING：铃声、STREAM_MUSIC：音乐声、STREAM_ALARM:警告声，STREAM_NOTIFICATION:通知声
 *  * 2.sampleRateInHz:采样率，即播放音频每秒钟会有多少次采样。如：8000，16000，22050、24000、44100、48000
 *  * 3.channelConfig：声道。AudioFormat中的可选值为CHANNEL_IN_MONO（单声道）。CHANNEL_IN_STEREO（立体声）
 *  * 4.audioFormat:采样格式，ENCODING_PCM_16BIT（16bit）、ENCODING_PCM_8BIT（8bit），注意，前者是可以兼容所有Android手机的。
 *  * 5.bufferSizeInBytes:AudioTrack内部的音频缓冲区的大小,通过getMinBufferSize来确定这个缓冲区的大小
 *  * 6.mode：播放模式，MODE_STATIC：需要一次性将所有的数据都写入播放缓冲区中，简单高效，通常用于播放铃声、系统提醒的音频片段、MODE_STREAM：需要按照一定的时间间隔不间断地写入音频数据，理论上它可以应用于任何音频播放的场景
 */
public class AudioTrackPlayer {
    private static final String TAG = "AudioTrackPlayer:";
    private static final int HZ = 0xac44;
    private AudioTrack audioTrack;

    private AudioTrackPlayer() {
        int minBufferSize = AudioTrack.getMinBufferSize(HZ, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT);
        LogUtil.log(TAG + "minBufferSize:" + minBufferSize);
        audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, HZ, AudioFormat.CHANNEL_CONFIGURATION_STEREO,
                AudioFormat.ENCODING_PCM_16BIT, minBufferSize * 2, AudioTrack.MODE_STREAM);
        audioTrack.setStereoVolume(1.0f, 1.0f);// 设置当前音量大小
        audioTrack.play();//调用play方法将AudioTrack切换到播放状态
    }

    private static AudioTrackPlayer instance = null;

    public static synchronized AudioTrackPlayer getAudioTrackPlayer() {
        if (instance == null) {
            instance = new AudioTrackPlayer();
        }
        return instance;
    }

    /**
     * 开始播放pcm文件
     *
     * @param pcmFile
     */
    public void start(File pcmFile) {
        new Thread() {
            @Override
            public void run() {
                try {
                    FileInputStream fileInputStream = new FileInputStream(pcmFile);
                    fileInputStream.skip(0x2c);
                    byte buffer[] = new byte[16 * 10000];
                    while (fileInputStream.read(buffer) >= 0) {
                        System.out.println("write pcm data");
                        audioTrack.write(buffer, 0, buffer.length);
                    }
                    fileInputStream.close();
                    fileInputStream = null;
                    audioTrack.stop();
                    audioTrack.release();
                    audioTrack = null;
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }.start();
    }

    /**
     * 停止播放
     */
    public void stop() {
        if (audioTrack != null) {
            audioTrack.stop();
        }
    }

    /**
     * 销毁
     */
    public void release() {
        if (audioTrack != null) {
            audioTrack.stop();
            audioTrack.release();
            audioTrack = null;
        }
    }
}
